/////////////////////////////////////////////////////////////////////////////
// Name:        using.h
// Purpose:     Usage page for the AxTk Doxygen manual
// Author:      Julian Smart
// RCS-ID:      $Id$
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////


/**

@page page_using Using AxTk

@li @ref page_using_overview
@li @ref page_adaptation
@li @ref page_using_dialogs
@li @ref page_using_menus
@li @ref page_online_help
@li @ref page_docs_and_views
@li @ref page_appearance_customisation
@li @ref page_shortcuts
@li @ref page_using_speech
@li @ref page_using_ax_resource

<hr>


@section page_using_overview Overview

Let's look at the main elements and classes in AxTk, and how they interact. First we'll
cover adaptation classes that you can use with your existing application; next we'll
examine the new menu system that you can consider using to make homogenous,
easy-to-navigate interfaces.

@section page_adaptation User interface adaptation classes

It can take just a few lines to adapt a dialog or frame to self-voicing.

@code
#include "ax/ax_ui_adaptation.h"

...


class MyDialog: public wxDialog
{
    ...
    AxSelfVoicing m_adapter;
};

MyDialog::MyDialog(...)
{
    ...
    m_adapter.Adapt(this);
}
@endcode

In addition, you need to create an AxViewManager class as described in the next section
to look after housekeeping tasks such as managing speech engines.

AxSelfVoicing is doing a lot behind the scenes - when Adapt is called, the control hierarchy
is examined and special event handlers derived from AxAdapter inserted into each control's event chain.
Each such event handler gives extra information about the control, for example the control's label,
a detailed description of the control's state, and so on. The event handler can respond to keyboard
input and can process shortcuts. All AxAdapter objects are removed in the AxSelfVoicing destructor,
so it's important to add an AxAdapter object to the window class, rather than create it on the stack.

How are these AxAdapter objects assigned to controls? This is done by instances of
AxVoiceAdaptationHandler, which are added to static lists in AxSelfVoicing on application startup.
Each AxVoiceAdaptationHandler object can recognize one or more controls and create
a corresponding AxAdapter for the ones it knows about. You can add further handlers if
you wish to extend the range of recognised controls.

You can also add an adapter explicitly on a control-by-control basis. You might want to do this
if you want to assign specific information to the adapter. Once you've added the adapter,
AxSelfVoicing::Adapt will ignore it and will not add a second adapter. Here's an example
of adding an adapter to a button to tell the system to read an alternate label:

@code
    wxButton* button = new wxButton(dialog, ID_PLAY, _(">"));
    AxSelfVoicing::AddAdapter(button, new AxButtonAdapter(_("Play")));
@endcode

@section page_using_dialogs Convenience dialogs

AxTk provides a number of dialogs to replace the relatively inaccessible dialogs in standard wxWidgets,
or to supply user interface functionality that cannot be supported with menus alone.

AxMessageBox and AxMessageDialog can be used in the same way as wxMessageBox and wxMessageDialog.
Instead of showing the message in a static text control, the text is displayed in a multiline text
control to make it easier to navigate to and around the message. Also, some extra buttons
are supported. You can pass wxYES_TO_ALL and wxNO_TO_ALL, which will be returned if the user
presses one of these buttons (the return values will be wxID_YESTOALL and wxID_NOTOTALL if using wxMessageDialog instead of
wxMessagBox).

AxTextInputDialog can be used in place of wxTextEntryDialog, and can be used to enter multiline
text if the flag axTEXTDIALOG_MULTILINE is passed. It makes use of the AxTextCtrl class which
supports the following keyboard shortcuts:

AxIdentifierReadCurrentWord, AxIdentifierReadNextWord, AxIdentifierReadPreviousWord, AxIdentifierReadCurrentSentence,
AxIdentifierReadNextSentence, AxIdentifierReadPreviousSentence, AxIdentifierReadCurrentParagraph,
AxIdentifierReadNextParagraph, AxIdentifierReadPreviousParagraph, AxIdentifierReadFromHere,
AxIdentifierReadAll, AxIdentifierDescribeContext, AxIdentifierStopSpeech, AxIdentifierPauseResumeSpeech.

AxShortcutInputDialog is similar to AxTextInputDialog but is specialised for entering the elements
of a shortcut one key at a time. It's used by AxShortcutsMenuItem for editing application shortcuts.

The AxLogGui class is not a dialog, but implements log display using an accessible dialog. You can
use it in your application initialisation as follows:

@code
    #include "ax/ax_log.h"
    ...
    
    delete wxLog::SetActiveTarget(new AxLogGui);
@endcode


@section page_using_menus The menu system

@subsection page_menus_intro Introduction to the menu system

With AxTk's alternate menu-based interface, the user primarily interacts with the application
via a control that acts as a menu. This can be implemented using any suitable control, but the default implementation
in AxTk uses a wxListCtrl. A typical user interface will consist of the menu control,
a menu title control, a description control, a view area for showing specific items,
and perhaps some buttons for commonly used commands such as going up and going home.
AxTk provides a default user interface with these elements in the form of AxContainerCtrl,
but you can provide your own if you wish.

A menu is represented by the AxMenu class, which contains one or more AxMenuItem objects.
An AxMenuItem object can have a submenu, and various subclasses define further behaviour
such as file browsing and toggling between two states.

The means by which the application processes events from the menu is a bit different from the way
wxWidgets normally works. Each AxMenuItem can have an AxActivator object, which has methods that
are called when the user selects or activates the menu item. However you can use the AxEventActivator
class and pass an event handler object and command identifier in order to send a wxCommandEvent to
an object, such as the main frame or application object.

When AxActivator::Activate is called by the system, an AxMenu object can be returned. If so,
the system takes control of the menu and the menu is shown. There is only one main menu,
and the system takes responsibility for managing the menu objects as soon as they are
handed over. If the application marks a menu item as dynamic, its submenu will be deleted
before showing a new one created by the same activator object, allowing for the fact
that data may change over time, and also allowing submenus to be cleaned up when not
in use.

Menu interaction and presentation is routed through an AxMenuController object, which knows what kind of control is
being used to implement the menu. The class AxStandardMenuController is provided using wxListCtrl as its menu control.
The controller object is passed to activation and other functions and the application can use functions in
the controller object, for example to refresh a menu item.

An AxTk application needs to store an AxViewManager object, usually a member of the application class.
AxViewManager stores the menu controller object and manages AxView objects which
are used to display information in the view area (typically on activation of a menu item).

To show your top-level menu, call AxViewManager::ShowInitialMenu.

@subsection page_menu_items Menu items and activators

AxTk provides a number of classes derived from AxMenuItem that provide useful pre-defined functionality. These include:

@li AxToggleMenuItem - when activated, toggles between two states, setting its value to the current state.
@li AxChoiceMenuItem - when activated, gets a value from a choice of strings, and sets its internal string value to the result.
@li AxAlertMenu - shows a menu of options or just a message, similar to a standard message box.
@li AxTextMenuItem - when activated, gets a text value from the user, and sets its internal string value to the result.
@li AxFolderMenuItem - when activated, gets a folder selection from the user, and sets its internal string value to the result.
@li AxFileMenuItem - when activated, gets a file selection from the user, and sets its internal string value to the result.
@li AxRangeMenuItem - when activated, shows a menu with 'Increase', 'Decrease' and 'Enter number' menu items, setting its internal integer variable to the result.
@li AxColourMenuItem - when activated, shows a menu of named colours.
@li AxGoUpMenuItem - when activated, goes up a level.
@li AxSpeechSettingsMenuItem - when activated, shows options for changing speech settings such as engine and voice.
@li AxVisualSettingsMenuItem - when activated, shows options for changing visual settings such as text size, text colour
and window colour.
@li AxShortcutsMenuItem - when activated, allows customisation of application shortcuts.

To achieve this functionality, some of the above use a modal menu, derived from AxModalMenu. This class
shows a temporary menu using AxModalMenu::ShowModal which interrupts program flow (and 'captures' the user in the submenu) until
an activator in the submenu calls AxModalMenu::EndModal. When the modal menu is destroyed, the previous
menu is restored.

You can use the modal menu functionality from an activator, without an associated AxMenuItem. For example
you could prompt for a string with AxModalChoiceMenu. The AxAlertModalMenu class doesn't have an
associated menu item since it's used for a temporary alert state.

Although menu items such as AxTextMenuItem and AxRangeMenuItem contain their own state storage,
you may wish to use a corresponding validator object such as AxTextValidator or AxRangeValidator
to link the menu item with a C++ variable. This is similar to wxValidator in regular wxWidgets
programming.

AxAutoUpdateActivator is a useful base class for activators that need to update their menu
items in idle time or just before the items are displayed. Derived classes need to
implement the CreateString function to provide the current label or description text
given a label or description specification that is stored in the AxAutoUpdateActivator class.
Typically, CreateString will be implemented by replacing a keyword in the specification
with the current value. AxAutoUpdateActivator takes care of implementing the BeforeDisplay
and UpdateUI function that the system calls to allow label updating to occur.

@subsection page_event_handling Event handling

Each AxMenuItem has a string identifier. Using strings instead of integers reduces the chances
of accidental identifier clashes, and the headache of allocating identifiers by hand.

Menu items send command events to the menu item when their values are changed. At the moment, AxTk reuses event
classes and types from wxWidgets, so for example AxRangeMenuItem will generate EVT_SPINCTRL when the user
changes the value. Command events are processed first by the menu item, then by its validator, and if not
processed by either, the event is passed up the menu hierarchy. Since menu items have string identifiers,
use the macro AxId to turn string identifiers into integers for passing to EVT_... macros. You can also
use the function AxGetId to return an integer identifier.

Here's an example of an event table defined for a menu item:

@code
BEGIN_EVENT_TABLE( AxSpeechSettingsMenuItem, AxMenuItem )
    EVT_CHOICE(AXID("SPEECHENGINE_MAIN"), AxSpeechSettingsMenuItem::OnSelectEngine)
    EVT_SPINCTRL(AXID("VOLUME_MAIN"), AxSpeechSettingsMenuItem::OnSelectVolume)
    EVT_CHECKBOX(AXID("ENABLE_MULTIPLEVOICES"), AxSpeechSettingsMenuItem::OnSelectMultipleVoices)
END_EVENT_TABLE()
@endcode

You can see examples of event handling in ax_menu_speech_settings.cpp.

@section page_online_help Managing online help

Current AxTk doesn't support full-blown online help, though it is expected that this will follow.
However it can support context-sensitive help, normally activated using the F1 key.

Add this to your application initialisation code:

@code
    #include "ax/ax_help_provider.h"
    ...

    wxHelpProvider::Set(new AxHelpProvider(& GetViewManager().GetSpeech()));
@endcode

AxHelpProvider implements a popup HTML window with speech output for the help strings
that you set for controls with wxWindow::SetHelpText.

For menu-based interfaces, menu items and menus have descriptions which are displayed
underneath the menu and are spoken when the item is described (depending on current verbosity level
and the operation that causes the item to be described).

@section page_docs_and_views Documents and views

If you're using the AxTk menu system, you are likely to use AxView and possibly AxDocument to manage information
displayed in the view pane, to the right of the menu. Views can be shown by menu activators or other code.
To create a view class, derive from AxView and override functions such as AxView::Initialize (create necessary windows)
and AxView::Activate (to show the UI with the appropriate document). In fact you don't need to associate a document
with a view; for example, with AxSummaryView you can just call AxSummaryView::SetDescription to display some text.

Here's some code that uses AxSummaryView to show initial text for the application:

@code
// Show the home view
bool AxViewManager::ShowHomeView()
{
    AxSummaryView* view = wxDynamicCast(FindOrCreateView(CLASSINFO(AxSummaryView)), AxSummaryView);
    if (view)
    {
        ActivateView(view, NULL);
        view->SetDescription(GetHomeDescription());
        
        // Set the focus back to the menu control in case it changed
        // when creating a view
        GetMenuCtrl()->SetFocus();
        return true;
    }
    return true;
}
@endcode

A view generally creates its window as a child of the pager control (similar to a notebook, but without any visible controller).
Here's how AxSummaryView initializes itself, by adding a named window to the pager control:

@code
bool AxSummaryView::Initialize(AxViewManager* viewManager)
{
    if (!GetWindow())
    {
        AxSummaryViewPanel* panel = wxDynamicCast(viewManager->GetViewPagerCtrl()->FindPageWindow(wxT("Summary")), AxSummaryViewPanel);
        if (!panel)
        {
            panel = new AxSummaryViewPanel(viewManager->GetViewPagerCtrl(), wxID_ANY);
            viewManager->GetViewPagerCtrl()->AddPage(panel, wxT("Summary"));
        }
        SetWindow(panel);
    }
    return true;
}
@endcode

Although showing one view at a time may seem restrictive, it provides a simple model for the visually impaired user to
interact with. However if you wish to provide a completely different interface, that's fine, though you'll still need
an AxViewManager instance in order to manage menu interaction and/or adaption of a conventional wxWidgets user interface.

Currently, AxDocument isn't used by the basic AxTk framework and its sample. However, AxDocument comes into its own in the
resource subsystem.

@section page_appearance_customisation Appearance customisation

Currently, the user can perform very simple customisation of the application text size and
colours. As the samples demonstrate, the Visual Settings menu has options for
text size, text colour, window colour, and panel colour. Each settings has a default option
which allows the platform defaults to be used.

The application can also control these settings programmatically via the AxVisualSettings class
which is accessed using AxViewManager::GetVisualSettings.

These settings can be loaded from and saved to wxConfig objects via AxVisualSettings::Load and
AxVisualSettings::Save, as shown in the samples to make the user choices persist between
sessions.

In future, visual schemes may be added to make it easier to choose multiple settings
at once, using names such as Large Text or High Contrast.

@subsection page_how_appearance_update_works How appearance update is implemented

The appearance is changed when AxViewManager::UpdateAppearance is called with an optional
window to start from and update hint. After calling AxMenuController::UpdateAppearance
(implemented by the specific menu controller class), the function sends a wxSysColourChangedEvent
to the specified window (or top-level window). Making use of this existing event means
that code that is already set up to handle colour changes may already work correctly.
If not, existing code can be extended easily to handle this event.

Also, each AxAdapter object associated with a control responds to this event and
calls the virtual functions AxAdapter::ApplyWindowColours and AxAdapter::ApplyFontSize,
which can be overridden by specific adapter classes. AxAdapter::PostUpdateAppearance
is called after an adapter's children have been sent the wxSysColourChangedEvent event,
to allow for a container window to adjust its layout as a result of changing text size.
This is performed automatically by AxPanel, but if you have custom layout code not
using wxWindow::Layout, you may wish to override this function.

See ax_ui_adaptation.h, ax_ui_adaptation.cpp, ax_ui_adaptation_standard.h and
ax_ui_adaptation_standard.cpp for examples.

@section page_shortcuts Managing shortcuts

It's important for a person with sight difficulties to be able to navigate around the user interface using the keyboard.
The wxShortcutManager class should be used to manage shortcuts, allowing easy customisation by the user.
Controls that have been adapted for speech will become sensitive to shortcuts, due to AxAdapter's own shortcut detection
code (independent from the wxWidgets accelerator table mechanism).

An AxTk application will add a wxShortcutManager member to the application class, and initialise the shortcuts with
code similar to this:

@code
#include "shortcutcust/shortcutcust.h"
...

/// Initialise custom shortcuts
void AxSampleApp::InitShortcuts()
{
    // Note that we use wxTRANSLATE for the names, since this must be unique whatever the
    // current language setting is. wxTRANSLATE indicates to tools such as poEdit that the
    // string should be translated, but this macro doesn't actually do the translation.
    // Instead, wxGetTranslation is used later when displaying the name in the menu.
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierGoUp),
                       wxTRANSLATE("Go up"), _("General Shortcuts"), _("Goes up to the previous menu"), wxACCEL_CTRL, (int) 'U'));
    GetShortcutManager().Add
        (wxShortcutItem(AxGetId(AxIdentifierGoHome),
                        wxTRANSLATE("Go home"), _("General Shortcuts"), _("Goes to the home menu"), wxACCEL_CTRL, (int) 'H'));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierStopSpeech),
                       wxTRANSLATE("Stop speaking"), _("General Shortcuts"), _("Stops speaking"), wxACCEL_CTRL, (int) 'G'));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierPauseResumeSpeech),
                       wxTRANSLATE("Pause or resume speech"), _("General Shortcuts"), _("Pauses or resumes speech"), wxACCEL_CTRL, (int) 'K'));
    
    ...
}
@endcode

Shortcuts can be saved to and loaded from a wxConfig object using wxShortcutManager::Save and wxShortcutManager::Load.

The shortcut manager should be associated with the view manager with code similar to:

@code
    wxGetApp().GetViewManager().SetShortcutManager(& wxGetApp().GetShortcutManager());
@endcode

Add a shortcut editor to your AxTk menu with this code:

@code
    menu->AddItem(new AxShortcutsMenuItem(controller, & wxGetApp().GetViewManager().GetSpeech(),
        & wxGetApp().GetShortcutManager(), this /* the window to set the shortcuts in */,
        GetMenuBar()));
@endcode

If your application has a frame menu bar, and you pass it to AxShortcutsMenuItem, its labels will be updated appropriately when the user assigns
a different shortcut.

You can use the identifiers defined in ax_menu.h, and you can also use your own identifiers. Many of the standard identifiers are
handled by event handlers in AxAdapter, but you can add your own event handlers to either your main frame class or (if you need them to
be active even when modal dialogs are shown) to your application class.


@section page_using_speech Using text to speech

@subsection page_using_speech_tts wxTextToSpeech

AxTk uses the wxTextToSpeech class, which is implemented separately from core AxTk but is currently included with the AxTk distribution.
wxTextToSpeech does not implement a specific speech engine, but instead supports an extensible handler system that makes
use of existing speech engines. Currently, wxTextToSpeech has handlers for Microsoft SAPI 5.1, Apple Speech Synthesis Manager,
eSpeak, and Cepstral. The handlers for the latter two engines use an external process to drive a command line version of the engine.

@subsection page_using_speech_axtk AxTk and speech

AxTk abstracts its speech capabilities a step further with the AxSpeech class that can handle up to two instances of wxTextToSpeech.
AxSpeech normally processes speech requests in idle time, which allows for utterances to be overridden by more pertinent ones
if necessary, before speech synthesis of the old speech event has started.

To speak some text, you can create an AxSpeechEvent object and pass it to AxSpeech, or you can
use the convenience function AxSpeech::Say to directly pass the text. The AxSpeechEvent objects
are processed (in idle time) by instances of AxSpeechEventHandler which make up an event handler chain.
By default, AxSpeech sets the handler to AxStandardSpeechEventHandler. Your application can call AxSpeech::Push to
insert a different handler at the front of the chain, and process speech events in a custom way by overriding
AxSpeechEventHandler::ProcessSpeechEvent.

An AxSpeechEvent has a string event type, which takes values such as AxSpeechEventActivateItem, AxSpeechEventRefreshMenu,
and AxSpeechEventText. Types such as AxSpeechEventActivateItem require the speech text to be constructed
from current values such as the current menu item, whereas AxSpeechEventText indicates a simple text string.

AxSpeechEvent contains a flag field, which consists of flags as follows:

@li AxSpeechFlagsPurge: purges previous speech events in the speech channel specified by the event.
@li AxSpeechFlagsPurgeAll: purges previous speech events on all channels
@li AxSpeechFlagsInviolate: don't allow this event to be purged
@li AxSpeechFlagsImmediate: start speaking immediately instead of waiting until system is idle
@li AxSpeechFlagsContentChannel: use content channel instead of main channel

You can use the simple AxSpeech::Say function to speak text:

@code
    GetViewManager().GetSpeech().Say(_("Welcome to the Eh Ex Tee Kay sample!"),
        AxSpeechFlagsInviolate); // This shouldn't be interrupted by other speech events.
@endcode

or you can create and pass an event object:

@code
    AxSpeechEvent event;

    // This is not the verbosity of this event, it's the verbosity with which
    // to describe the event.
    event.SetVerbosityPolicy(describeAtVerbosity);
    event.SetSpeechEventType(AxSpeechEventDescribeItem);
    event.SetFlags(AxSpeechFlagsPurge);
    event.SetMenu(item->GetParent());
    event.SetMenuItem(item);

    GetViewManager().GetSpeech().EmitSpeech(event);
@endcode

@subsection page_using_speech_verbosity Controlling verbosity

AxSpeech stores speech policy - that is, high-level speech settings that can be changed by the user - using
a class called AxSpeechPolicy. As well as containing the switch for switching speech on and off,
it stores the current verbosity, which is a number between 1 and 5 and determines how much
speech is emitted. 1 is least verbose, and 5 is most verbose; the default is 3.

AxSpeechEvent also stores a verbosity policy that tells the speech event handlers the threshold
for this particular speech event. So if you specify a verbosity of 2 in the speech event, then
if the global verbosity is 2 or more, it will be spoken. If you specify a verbosity of 1 in the speech event,
it will always be spoken.

@subsection page_using_speech_channels Channels: using multiple voices simultaneously

AxSpeech supports the concept of 'channel'. There are two channels, represented by integers
0 and 1 or AxSpeechMainChannel and AxSpeechContentChannel. Each channel has a corresponding
wxTextToSpeech object and for those engines that support it, they can be used
simultaneously. This is useful when outputting content without interrupting it with
user interface navigation speech. The user can specify parameters such as voice and speed
independently for each channel, and it's likely that you will want to use a different
voice for each channel.

Specify the content channel in a AxSpeechEvent by passing the AxSpeechFlagsContentChannel flag.
Otherwise, the main channel will be used.

Note that not all engines are capable of outputting speech to more than one channel at a time.
Some engines will simply crash, as they are not designed to be re-entrant. wxTextToSpeech
has a function wxTextToSpeech::VoicesAreCompatible and AxTk will use it to try to determine
whether to switch off two channel operation. However it's possible that you may be using a
speech engine that isn't covered; so for SAPI, you can call wxTTSSapiHandler::SetSimultaneousVoiceExclusions
to set the strings that will be matched against SAPI voices to determine whether an engine
can be used multiple times simultaneously. See also todo.txt for notes about problems with
wxTTSProcessHandler::Stop which contribute to problems with simultaneous engine usage.


@section page_using_ax_resource Using AxResourceLibrary

This is an optional layer on top of AxTk, that maintains a library of resources which can be
audio files, ebooks, text documents, utilities, web services, or whatever might be a useful
feature of the application. The motivation is to present users with a uniform and easy way to access their data and
important functionality. Providing this in AxTk means that others can take an already useful
system (in particular with support for popular audio and ebook formats) and build upon it, providing custom solutions.

The intention is to separate out the major functionality from the way it's used in AxTk, where possible. So for example
the guts of Epub manipulation will be done in AxTk-neutral classes, with AxTk-specific classes to
integrate the functionality. This allows programmers to integrate the functionality in different ways, as
well as making maintenance easier.

The sample in @c samples/ax_resource/resource_sample can scan folders containing audio files and Epub files,
and can then play albums and read Epub books (converting the XHTML content to plain text).


*/
